/**
 * @title ShiroUtil.java
 * @package com.baikeyang.common.util.shiro
 * @description TODO
 * @author BaiKeyang@vip.qq.com
 * @date 2016年2月18日 上午9:54:11
 * @version v1.0.0
 * @copyright Youth Pro.
 */
package com.baikeyang.common.util.shiro;

import com.baikeyang.common.constant.EncryptionConstants;
import com.baikeyang.common.util.EncodeUtil;
import com.baikeyang.common.util.EncryptUtil;
import com.baikeyang.common.util.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

/**
 * @title ShiroUtil.java
 * @package com.baikeyang.common.util
 * @description 安全认证工具类
 * @author BaiKeyang@vip.qq.com
 * @date 2016年1月26日 下午1:18:50
 * @version v1.0.0
 * @copyright Youth Pro.
 */
public class SecurityUtil {

    private SecurityUtil(){}

    public static boolean login(String username, String password) {
    	try {
	        getSubject().login(new UsernamePasswordToken(username, password));
	        return true;
        } catch (AuthenticationException e) {
        	throw e;
        }
    }

    public static boolean login(String username, String password, String captcha) {
        try {
            getSubject().login(new UsernamePasswordToken(username, password));
            return true;
        } catch (AuthenticationException e) {
            throw e;
        }
    }

    public static PrincipalCollection getPrincipals() {
        return getSubject().getPrincipals();
    }

	public static Subject getSubject() {
		return SecurityUtils.getSubject();
	}


	public static Session getSession() {
		return getSubject().getSession();
	}

	public static Object getAttribute(String key) {
		return getSession().getAttribute(key);
	}

	public static void setAttribute(String key, Object obj) {
		getSession().setAttribute(key, obj);
	}

	public static void setTimeout(long timeout) {
		getSession().setTimeout(timeout);
	}

	public static boolean hasRole(String role) {
		return getSubject().hasRole(role);
	}

	public static void checkRole(String role) {
		getSubject().checkRole(role);
	}

	/**
	 * 使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission 默认支持的实现方式
	 * 这里分别代表了 资源类型：操作：资源ID
	 * @param permission
	 * @return
	 */
	public static boolean isPermission(String permission) {
		return getSubject().isPermitted(permission);
	}

	public static void checkPermission(String permission) {
		getSubject().checkPermission(permission);
	}

	public static boolean isAuthenticated() {
	    return getSubject().isAuthenticated();
	}

	/**
	 * @title encryptPassword
	 * @description 加密用户登录密码
	 * @param password 密码
	 * @return String 加密后的密码
	 */
	public static String encryptPassword(String password) {
		return encryptPassword(password, null);
	}

	/**
	 * @title encryptPassword
	 * @description 根据指定的加密类型加密密码数据
	 * @param password 密码
	 * @param encryptType 加密方式 {SHA-1 | MD5}
	 * @return String
	 */
	public static String encryptPassword(String password, String encryptType) {
		if(StringUtils.isNotEmpty(encryptType) && EncryptionConstants.MD5.equals(encryptType)) { // MD5加密
			byte[] md5Password  = EncryptUtil.md5(password.getBytes(), EncryptionConstants.SHA_ITERATION_NUM);
			return EncodeUtil.encodeHex(md5Password);
		} else {
			byte[] salt = EncryptUtil.generateSalt(EncryptionConstants.SALT_SIZE);
			byte[] shaPassword  = EncryptUtil.sha1(password.getBytes(), salt, EncryptionConstants.SHA_ITERATION_NUM);
			return EncodeUtil.encodeHex(salt) + EncodeUtil.encodeHex(shaPassword);
		}
	}

	/**
	 * 验证密码
	 * @param plainPassword 明文密码
	 * @param password 密文密码
	 * @param encryptType 加密方式 {SHA-1 | MD5}
	 * @return 验证成功返回true
	 */
	public static boolean validatePassword(String plainPassword, String password, String encryptType) {

		byte[] encrPassword = null;
		if(StringUtils.isNotEmpty(encryptType) && encryptType.equals(EncryptionConstants.MD5)) {
			encrPassword = EncryptUtil.md5(plainPassword.getBytes(), EncryptionConstants.SHA_ITERATION_NUM);
			return password.equals(EncodeUtil.encodeHex(encrPassword));
		} else {
			byte[] salt = EncodeUtil.decodeHex(password.substring(0,16));
			encrPassword = EncryptUtil.sha1(plainPassword.getBytes(), salt, EncryptionConstants.SHA_ITERATION_NUM);
			return password.equals(EncodeUtil.encodeHex(salt) + EncodeUtil.encodeHex(encrPassword));
		}
	}

	public static boolean validatePassword(String plainPassword, String password) {
		return validatePassword(plainPassword, password, null);
	}

	/*
	@Deprecated
	public static Organization getCurrentOrg() {
        Object orgObj = getSession().getAttribute(Constants.SESSION_USER_ORG_KEY);
        if(null != orgObj) {
            return (Organization) orgObj;
        } else {
            return null;
        }
    }
    */

	/*
	@Deprecated
    public static String getCurrentOrgId() {
        Organization org = getCurrentOrg();
        return org == null ? null : org.getId();
    }
    */

	public static void main(String[] args) {
	    // 0cb506c8c95a66e87c463bf1a270446c
	    System.out.println(encryptPassword("123456", EncryptionConstants.MD5));
    }
}
